<?php
/**
 * Created by PhpStorm.
 * Power By Mikkle
 * Email：776329498@qq.com
 * Date: 2017/11/7
 * Time: 11:04
 */

namespace app\console\command\webim;

use app\common\library\token\driver\Redis;
use mikkle\tp_swoole\WebsocketServer;
use think\Request;
use think\Db;
use app\common\library\Token;
use app\common\library\Auth;

class WebSocket extends WebsocketServer
{

    protected $redis;
    protected $auth = null;
    protected $client_ids = [];
    /**
     * 初始化的回调方法
     * Power: Mikkle
     * Email：776329498@qq.com
     * @param \swoole_websocket_server $server
     */
    public function initialize(\swoole_websocket_server $server)
    {
        $this->redis = new \think\cache\driver\Redis();
        $this->auth = Auth::instance();
    }

    /**
     * 创建链接时候的回调方法
     * Power: Mikkle
     * Email：776329498@qq.com
     * @param \swoole_websocket_server $server
     * @param \swoole_http_request $request
     */
    public function onOpen(\swoole_websocket_server $server, \swoole_http_request $request)
    {

    }


    /**
     * 接收信息回调方法
     * Power: Mikkle
     * Email：776329498@qq.com
     * @param \swoole_websocket_server $server
     * @param \swoole_websocket_frame $frame
     */
    // 收到数据时回调函数
    public function onMessage(\swoole_websocket_server $server, \swoole_websocket_frame $frame)
    {
        if( strtoupper($frame->data) == 'PING' ){
            $server->push($frame->fd,'PONG');
        }else{
            $receive_data = json_decode($frame->data);
            switch ( $receive_data->type ){
                case 'bind':
                    //关系绑定
                    $this->redis->set('fd_'.$receive_data->uid,$frame->fd);
                    $this->redis->set('fdname_'.$frame->fd,$receive_data->uid);
                    break;
                case 'bindUser':
//                    $this->redis->set('homefd_'.$receive_data->token,$frame->fd);
//                    $this->redis->set('fdhome_'.$frame->fd,$receive_data->token);
//                    break;
                case 'bindClient':
//                    if( $client_ids = $this->redis->get('client_id') ){
//                        $this->client_ids[$frame->fd] = $frame->fd;
//                        $this->redis->set('client_id',$this->client_ids);
//                    }else{
//                        $this->client_ids = [$frame->fd => $frame->fd];
//                        $this->redis->set('client_id',$this->client_ids);
//                    }
//                    break;
                case 'room':
                    //绑定身份,插入数据库,更新数据库
                    $now = time();
                    $user = Db::name('onlineuser')
                        ->where('uid',$receive_data->uid)
                        ->where('room_id',$receive_data->roomId)
                        ->where('room_level',$receive_data->room_level)
                        ->find();
                    if( $user ){
                        Db::name('onlineuser')
                            ->where('id',$user['id'])
                            ->where('room_id',$receive_data->roomId)
                            ->update(['status'=>1,'onlinetime'=>$now,'fd'=>$frame->fd]);//更新为在线
                    }else{
                        Db::name('onlineuser')->insert([
                            'uid'       => $receive_data->uid,
                            'room_id'   => $receive_data->roomId,
                            'fd'        => $frame->fd,
                            'status'    => 1,
                            'createtime'=> $now,
                            'onlinetime'=> $now,
                            'room_level'=> $receive_data->room_level
                        ]);
                    }
                    break;
                default:
                    break;
            }
        }
    }


    public function onRequest(\swoole_websocket_server $server, \swoole_http_request $request, \swoole_http_response $response)
    {
        $data = $request->post ? $request->post : $request->get;
        $uids = Db::name('admin')->column('id');
        switch ($data['type']){
            case 'sendhome':
                $token = $data['token'];
                $fd = (int)$this->redis->get('homefd_' . $token);
                if ($fd > 0) {
                    $server->push($fd, json_encode($data['message'], JSON_UNESCAPED_UNICODE));
                }
                break;
            case 'bet':
                foreach ($uids as $uid) { //后端管理员推送
                    $fd = (int)$this->redis->get('fd_' . $uid);
                    if ($fd > 0) {
                        $data['message'] = "账号:{$data['username']}下注:{$data['money']}";
                        $server->push($fd, json_encode($data));
                    }
                }
                break;
            case 'tixian':
                foreach ($uids as $uid) { //后端管理员推送
                    $fd = (int)$this->redis->get('fd_' . $uid);
                    $connection = $server->connection_info($fd);
                    if ($fd > 0 && $connection === true && $connection['websocket_status'] == 3 ) {
                        $data['message'] = "账号:{$data['username']}提现:{$data['money']}";
                        $server->push($fd, json_encode($data));
                    }
                }
                break;
            case 'client_id':
                $minrates = $this->redis->get('minrate');
                foreach ($minrates as $k=>$v ){
                    $minrates[$k]['rate'] = $v['rate']/1000 .'%';
                }
                foreach ( $this->redis->get('client_id') as $item ){
                    $connection = $server->connection_info($item);
                    if( $connection === true && $connection['websocket_status'] == 3 ){
                        $server->push($item, json_encode([
                            'type'  => 'wave',
                            'msg'   => $minrates
                        ],true));
                    }
                }
                break;

            case 'bettoclient':
                $onlineusers = Db::name('onlineuser')
                    ->where('room_id',$data['info']['roomId'])
                    ->where('room_level',$data['info']['room_level'])
                    ->where('status',1)->select();
                foreach ( $onlineusers as $k=>$v ){
                    $connection = $server->connection_info($v['fd']);
                    if( $connection['websocket_status'] == 3 ){//用户正常在线是可以进行消息推送
                        $server->push($v['fd'],json_encode([
                            'type'  => 'bettoclient',
                            'msg'   => $data['info']
                        ])); //推送消息格式
                    }
                }
                break;
            case 'zj':
                $onlineuser = Db::name('onlineuser')
                    ->where('uid',$data['info']['user_id'])
                    ->where('status',1)->find();
                if( $onlineuser ){
                    $connection = $server->connection_info($onlineuser['fd']);
                    if( $connection['websocket_status'] == 3 ){//用户正常在线进行消息推送
                        $server->push($onlineuser['fd'],json_encode([
                            'type'  => 'zj',
                            'msg'   => $data['info']
                        ]));
                    }
                }
                break;
            default:
                break;
        }

    }

    // 连接关闭时回调函数
    public function onClose(\swoole_websocket_server $server, $fd)
    {

        //取消关系绑定
        $redis = new \think\cache\driver\Redis();
        $fdname_fd = $redis->get('fdname_'.$fd);
        $fd_uid = $redis->get('fd_'.$fdname_fd);
        if( $fdname_fd ){
            if(  $fd_uid ){
                $redis->rm('fd_'.$fdname_fd);//删除fd_uid键的缓存 后端
            }
            $redis->rm('fdname_'.$fd);//删除fd_name 缓存
        }

        //链接关闭，更新用户在线状态
        Db::name('onlineuser')->where('fd',$fd)->update([
            'status'        => 0,
            'offlinetime'   => time()
        ]);

        //关闭客户端删除，redis键值对，重新赋值
        $client_ids = $redis->get('client_id');
        if( $client_ids ){
            unset($client_ids[$fd]);
        }
        $redis->set('client_id',$client_ids);
    }


}